import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import n4j.call_tree as ct
import math


global g_zhongli, length
g_zhongli = 100
length = 20


def virtual_node(map, num):
    zuobiao = map.Firstzuobiao
    if abs(zuobiao.max()) < abs(zuobiao.min()):
        banjin = abs(zuobiao.min())
    else:
        banjin = abs(zuobiao.max())
    banjin = (int(banjin / 100) * 100) + 1500
    vir_zuobiao = []
    for i in range(num):
        x = banjin * math.cos(2 * i * math.pi / num)
        y = banjin * math.sin(2 * i * math.pi / num)
        tempzuobiao = np.array([x, y])
        vir_zuobiao.append(tempzuobiao)
    vir_zuobiao = np.array(vir_zuobiao)
    # print('往往', vir_zuobiao)
    return vir_zuobiao


def randmove(shape):
    return 5 * (np.random.random(shape)-0.5)


def Gravity(map, iterations, movenode_no, sumnode_no, irtime, gravity=0):
    ir = 0.9997
    ir = 1
    global g_zhongli
    if gravity:
        g_zhongli = gravity
    # map.Firstzuobiao = map.Firstzuobiao + randmove(map.Firstzuobiao.shape)
    dongdedian_no = movenode_no
    if irtime == 0:
        movenode_zuobiao = map.Firstzuobiao[dongdedian_no]
    else:
        movenode_zuobiao = map.virzuobiao[dongdedian_no]
    movenode_weight = map.nodeweight[dongdedian_no]
    # sum_zuobiao = map.Firstzuobiao[sumnode_no]
    # sum_weight = map.nodeweight[sumnode_no].T
    sum_zuobiao = map.virzuobiao[sumnode_no]
    sum_weight = map.virnodeweight[sumnode_no].T
    # bian_map = map.map[dongdedian_no, :][:, sumnode_no]
    bian_map = map.virmap[dongdedian_no, :][:, sumnode_no]
    # print(bian_map)
    bian_no = []
    for i in range(len(bian_map)):
        for j in range(len(bian_map[i])):
            if bian_map[i][j] != 0 and i < j:
                bian_no.append([i, j])
    # print('www', bian_no)
    # print(len(bian_no))
    bian_no = np.array(bian_no)
    bian_no = bian_no.T
    bian_no = (bian_no[0], bian_no[1])
    vir_zuobiao = virtual_node(map, 4)
    sum_zuobiao = np.vstack((sum_zuobiao, vir_zuobiao))
    sum_weight = np.hstack((sum_weight, np.full((1, 4), 8)))
    # print('da', sum_weight)
    # print(sum_zuobiao)
    movenode_in_sumnode = []
    for i in movenode_no:
        movenode_in_sumnode.append(sumnode_no.index(i))
    # print('我', movenode_in_sumnode)
    for m in range(iterations):
        temp_long = np.array([sum_zuobiao] * len(movenode_zuobiao))
        # print('kaishi', temp_long.shape)
        temp_long = temp_long.transpose(1, 0, 2)
        temp_long = -(temp_long - movenode_zuobiao)
        temp_x = temp_long[:, :, 0]
        temp_y = temp_long[:, :, 1]
        d_2 = temp_x * temp_x + temp_y * temp_y
        Dio_d = d_2 ** 0.5
        d_1 = Dio_d.T
        # print('ssss', d_1.shape)
        # print(d_1)
        Dio_d = np.dstack((Dio_d, Dio_d))
        Dio_d = temp_long / Dio_d
        Dio_d[np.isnan(Dio_d)] = 0
        # print('w', Dio_d.shape)
        # print('www', Dio_d)
        Dio_d = Dio_d.transpose(1, 0, 2)
        tyinli = np.zeros(d_1.shape)
        # 这个地方数据要求很奇怪
        tyinli[bian_no] = (d_1[bian_no] - length) #* 1000
        tyinli[tyinli < 0] = 0
        tyinli = np.dstack((tyinli, tyinli))
        tyinli = -Dio_d * tyinli
        d_2 = d_2.T
        # print('d_2',d_2.shape)
        d_2daoshu = 1 / d_2
        d_2daoshu[np.isinf(d_2daoshu)] = 0
        # print('w1', d_2daoshu[d_2daoshu > 1/40000])
        # print(d_2daoshu)
        # d_2daoshu[d_2daoshu > 1 / 40000] = 1 / ((d_2[d_2daoshu > 1 / 40000] ** 0.5) * 200)
        tchili = d_2daoshu * g_zhongli * sum_weight * movenode_weight
        tchili = np.dstack((tchili, tchili))
        tchili = tchili * Dio_d
        # print('sw', tchili.shape, tyinli.shape)
        # print(tchili)
        # print(tyinli)
        D_movenode_zuobiao = tyinli.sum(1) + tchili.sum(1)

        D_movenode_zuobiao = D_movenode_zuobiao / (movenode_weight * 2)  # 一月六号是5

        movenode_zuobiao = movenode_zuobiao + D_movenode_zuobiao*ir
        sum_zuobiao[movenode_in_sumnode] = movenode_zuobiao
        if m > 10:
            ir = ir * ir
        # print(ir)
    # map.Firstzuobiao[sumnode_no] = sum_zuobiao[0:len(sumnode_no)]
    map.virzuobiao[sumnode_no] = sum_zuobiao[0:len(sumnode_no)]
    # print(bian_no)
    return map.virzuobiao
